#!/usr/bin/env python
# -*- coding:utf-8 -*-
# Create by zhang
# Create on 2022/6/27 17:59
from abc import ABCMeta, abstractmethod
from typing import List
from sys import maxsize

from infrastructure.filter.order import Order


class FilterInterface(metaclass=ABCMeta):
    def __init__(self):
        super(FilterInterface, self).__init__()

    @abstractmethod
    def filter(self, request) -> None:
        raise Exception('子类中必须实现该方法')

class AbstractFilterChain(FilterInterface):
    def __init__(self):
        super(AbstractFilterChain, self).__init__()
        self.chain: List[FilterInterface] = []

    def append(self, filter:FilterInterface) -> bool:
        return self.insert(filter, index=maxsize)

    def insert(self, filter:FilterInterface, index:int=maxsize):
        if filter and filter not in self.chain:
            if index < 0:
                self.chain = [filter] + self.chain
                return True
            elif index >= len(self.chain):
                self.chain.append(filter)
                return True
            else:
                self.chain = self.chain[0:index] + [filter] + self.chain[index:]

    def get_index(self, filter:FilterInterface):
        for i, f in enumerate(self.chain):
            if f.__class__ == filter.__class__:
                return i
        return -1

    def __contains__(self, item:FilterInterface):
        for f in self.chain:
            if f.__class__ == item.__class__:
                return True
        return False


class FilterChain(AbstractFilterChain):
    def __init__(self):
        super(FilterChain, self).__init__()

    def add_after(self,new_filer:FilterInterface, target_filter:FilterInterface):
        index = self.get_index(target_filter)
        if index >= 0 and index < len(self.chain):
            return self.insert(new_filer, index=index)
        return False

    def add_before(self,new_filer:FilterInterface, target_filter:FilterInterface):
        index = self.get_index(target_filter)
        if index >= 0 and index < len(self.chain):
            return self.insert(new_filer, index=index-1)
        return False

    def filter(self, request) -> None:
        for f in self.chain:
            f.filter(request)


class OrderFilterInterface(FilterInterface, Order):
    def __init__(self, order:int = 0):
        super(OrderFilterInterface, self).__init__(order=order)


class OrderFilterChain(AbstractFilterChain, Order):
    def __init__(self, order:int = 1):
        super(OrderFilterChain, self).__init__(order=order)

    def filter(self, request) -> None:
        self._order()
        for f in self.chain:
            f.filter(request)

    def _order(self) -> None:
        self.chain.sort(lambda f: f.trade)
